package org.gesplan.ui;

import ca.odell.glazedlists.swing.AutoCompleteSupport;
import java.awt.EventQueue;
import java.beans.Beans;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.persistence.RollbackException;
import javax.swing.JFrame;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import org.gesplan.controller.GenericController;
import org.gesplan.controller.MaterialJpaController;
import org.gesplan.entity.Material;
import org.gesplan.entity.MaterialFamily;
import org.gesplan.exceptions.NonexistentEntityException;
import org.gesplan.listeners.LoggingBindingListener;
import org.gesplan.listeners.SelectionListener;
import org.gesplan.util.ExcelManager;
import org.gesplan.util.Utils;
import org.jdesktop.observablecollections.ObservableCollections;
import org.jdesktop.swingbinding.JTableBinding;


/**
 *
 * @author Roger
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class MaterialPanel extends AbstractPanel {

    private JTableBinding jTableBinding;
    private Material material = null;
    private MaterialBuildingPanel mbp = null;    
    private static AutoCompleteSupport supportMaterial;    


    public MaterialPanel() {
        this(null, null);
    }

    
    public MaterialPanel(Material material, MaterialBuildingPanel mbp) {
        super();
        this.material = material;
        this.mbp = mbp;        
        try {
            initComponents();
        } catch (Exception e) {
            logger.log(Level.SEVERE, bundle.getString("ERROR_DB_CONNECTION"), e);
        }
        if (!Beans.isDesignTime()) {
            initConfig();
        }
    }    


    private void initConfig() {

        super.abstractTable = masterTable;
        super.abstractQuery = tableQuery;
        super.abstractList = tableList;

        // Add Listeners
        LoggingBindingListener lbl = new LoggingBindingListener(saveButton);
        bindingGroup.addBindingListener(lbl);
        masterTable.getSelectionModel().addListSelectionListener(new SelectionListener(masterTable));

        // Autocomplete Support for combos
        GenericController.fillComboBox(bundle.getString("qrySupplier"), supplierComboBox);
        GenericController.fillComboBox(bundle.getString("qryMaterialFamily"), materialFamilyComboBox);
        supportMaterial = GenericController.fillComboBox(bundle.getString("qryMaterial"), filterMaterialComboBox);
        GenericController.fillComboBox(bundle.getString("qryMaterialFamily"), filterMaterialFamilyComboBox);

        initSorter();
        setHeaders();

        // If we came from MaterialBuildingPanel with a selected material
        if (material != null) {
            filterMaterialComboBox.setSelectedItem(material);
            ListSelectionModel selectionModel = masterTable.getSelectionModel();
            if (selectionModel.getMaxSelectionIndex() > -1){
                selectionModel.setSelectionInterval(0, 0);
            }
        }

    }

    
    private void refreshMaterials(){
        supportMaterial = GenericController.fillComboBox(bundle.getString("qryMaterial"), filterMaterialComboBox, supportMaterial);           
    }
    

    private void setHeaders() {
        Utils.setTableHeader(masterTable);
        masterTable.getColumnModel().getColumn(0).setResizable(false);
        masterTable.getColumnModel().getColumn(1).setPreferredWidth(200);
        masterTable.getColumnModel().getColumn(5).setPreferredWidth(150);
    }


    private void changeFilter() {

        if (Utils.isLoaded()) {
            
            Material material = null;
            MaterialFamily materialFamily = null;
            String filterMaterial = null;
            String filterFamily = null;            

            // Get Filters
            if (filterMaterialComboBox.getSelectedItem() instanceof Material) {
                material = (Material) filterMaterialComboBox.getSelectedItem();
            } else {
                filterMaterial = (String) filterMaterialComboBox.getSelectedItem();
            }
            if (filterMaterialFamilyComboBox.getSelectedItem() instanceof MaterialFamily) {
                materialFamily = (MaterialFamily) filterMaterialFamilyComboBox.getSelectedItem();
            } else {
                filterFamily = (String) filterMaterialFamilyComboBox.getSelectedItem();
            }
            
            // Build JQL Query
            String jql = "SELECT m FROM Material m ";
            String where = null;
            if (filterMaterial != null) {
                where = "WHERE ";
                where += "(m.id like '%" + filterMaterial + "%') OR (m.description like '%" + filterMaterial + "%')";
            }
            if (material != null) {
                where = (where == null) ? "WHERE " : where + " AND ";
                where += "m.id = '" + material.getId() + "'";
            }
            if (filterFamily != null) {
                where = (where == null) ? "WHERE " : where + " AND ";
                where += "m.materialFamilyId.description like '%" + filterFamily + "%'";
            }
            if (materialFamily != null) {
                where = (where == null) ? "WHERE " : where + " AND ";
                where += "m.materialFamilyId.id = '" + materialFamily.getId() + "'";
            }

            if (where != null) {
                jql += where;
            }
            jql += " ORDER BY m.description";
            updateTableBinding(jql);
            
        }

    }


	private void updateTableBinding(String jql) {
        
        tableQuery = entityManager.createQuery(jql);
        tableList = ObservableCollections.observableList(tableQuery.getResultList());
        jTableBinding.unbind();
        jTableBinding.setSourceObject(tableList);
        jTableBinding.bind();
        masterScrollPane.setViewportView(masterTable);
        setHeaders();
        
    }


    private void resetFilters() {
        filterMaterialComboBox.setSelectedIndex(-1);
        filterMaterialFamilyComboBox.setSelectedIndex(-1);
    }


    private void changePrice() {
        
        try {
            double price = (double) Double.parseDouble(priceSupplierField.getText().replace(",", "."));
            double iva = (double) Double.parseDouble(ivaField.getText().replace(",", "."));
            double pvp = (price * (1 + iva));
            DecimalFormat twoDForm = new DecimalFormat("#.##");
            Double doubleAux = (Double) Double.parseDouble(twoDForm.format(pvp).replace(",", "."));                
            pvpFieldOk.setText(doubleAux.toString());  
        } catch (Exception e) {
            logger.warning(bundle.getString("VALIDATE_NUMBER3") + ": " + e.getMessage());
        }
        
    }


    private void prepareReport() {
        
        String where = null;
        MaterialFamily materialFamily = (MaterialFamily) filterMaterialFamilyComboBox.getSelectedItem();        
        if (materialFamily != null) {
            where = "WHERE ";
            where += "material_family_id = '" + materialFamily.getId() + "'";
        }
        ExcelManager.reportMaterialsList(where);
        
    }


    @Override
    protected void newRecord() {
        
        Material object = new Material();
        entityManager.persist(object);
        tableList.add(object);
        super.newRecord();
        
    }


    @Override
    protected void save() {
        
        int selected = masterTable.getSelectedRow();
        if (selected > -1) {
            Material object = tableList.get(masterTable.convertRowIndexToModel(selected));
            MaterialJpaController dao = new MaterialJpaController();
            try {
                dao.edit(object);
                logger.info("Material.save: " + object.getId());
            } catch (NonexistentEntityException ex) {
                logger.severe(ex.getMessage());
            } catch (Exception ex) {
                logger.severe(ex.getMessage());
            }
            refreshMaterials();            
            if (mbp != null){
                mbp.refreshMaterials();
            }
        }
        
    }


    @Override
    protected void delete() {
        
        if (deleteConfirm()) {
            List<Material> toRemove = new ArrayList<>(masterTable.getSelectedRows().length);
            MaterialJpaController dao = new MaterialJpaController();
            for (int idx = 0; idx < masterTable.getSelectedRows().length; idx++) {
                Material object = tableList.get(masterTable.convertRowIndexToModel(masterTable.getSelectedRows()[idx]));
                try {
                    toRemove.add(object);
                    dao.destroy(object.getId());
                    logger.info("Material.delete: " + object.getId());
                } catch (NonexistentEntityException | RollbackException ex) {
                    logger.severe(ex.getMessage());
                }                
            }
            refreshMaterials();                 
            tableList.removeAll(toRemove);
            if (mbp != null){
                mbp.refreshMaterials();
            }            
        }
        
    }

    // <editor-fold defaultstate="collapsed" desc="Auto Generated Code">

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        tableQuery = Beans.isDesignTime() ? null : entityManager.createQuery(bundle.getString("qryMaterial"));
        tableList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : org.jdesktop.observablecollections.ObservableCollections.observableList(tableQuery.getResultList());
        materialFamilyQuery = Beans.isDesignTime() ? null : entityManager.createQuery(bundle.getString("qryMaterialFamily"));
        materialFamilyList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : materialFamilyQuery.getResultList();
        floatValidator1 = new org.gesplan.util.FloatValidator();
        floatToStringConverter1 = new org.gesplan.util.FloatToStringConverter();
        materialQuery = Beans.isDesignTime() ? null : entityManager.createQuery(bundle.getString("qryMaterial"));
        materialList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : materialQuery.getResultList();
        masterScrollPane = new javax.swing.JScrollPane();
        masterTable = new javax.swing.JTable();
        idLabel = new javax.swing.JLabel();
        descriptionLabel = new javax.swing.JLabel();
        pvpLabel = new javax.swing.JLabel();
        priceSupplierLabel = new javax.swing.JLabel();
        ivaLabel = new javax.swing.JLabel();
        materialFamilyIdLabel = new javax.swing.JLabel();
        unitsLabel = new javax.swing.JLabel();
        datePvpLabel = new javax.swing.JLabel();
        idField = new javax.swing.JTextField();
        descriptionField = new javax.swing.JTextField();
        priceSupplierField = new javax.swing.JTextField();
        ivaField = new javax.swing.JTextField();
        unitsField = new javax.swing.JTextField();
        materialFamilyComboBox = new javax.swing.JComboBox();
        buttonsPanel = new javax.swing.JPanel();
        nextButton = new javax.swing.JButton();
        previousButton = new javax.swing.JButton();
        refreshButton = new javax.swing.JButton();
        saveButton = new javax.swing.JButton();
        deleteButton = new javax.swing.JButton();
        newButton = new javax.swing.JButton();
        supplierComboBox = new javax.swing.JComboBox();
        materialFamilyIdLabel1 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        materialFamilyIdLabel2 = new javax.swing.JLabel();
        pvpDateChooser = new com.toedter.calendar.JDateChooser();
        filterMaterialComboBox = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        filterMaterialFamilyComboBox = new javax.swing.JComboBox();
        resetButton = new javax.swing.JButton();
        reportButton = new javax.swing.JButton();
        pvpFieldOk = new javax.swing.JTextField();

        FormListener formListener = new FormListener();

        masterTable.setAutoCreateRowSorter(true);

        org.jdesktop.swingbinding.JTableBinding jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, tableList, masterTable, "provaList");
        org.jdesktop.swingbinding.JTableBinding.ColumnBinding columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${id}"));
        columnBinding.setColumnName("Id");
        columnBinding.setColumnClass(String.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${description}"));
        columnBinding.setColumnName("Descripció");
        columnBinding.setColumnClass(String.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${priceSupplier}"));
        columnBinding.setColumnName("Preu proveïdor");
        columnBinding.setColumnClass(Float.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${iva}"));
        columnBinding.setColumnName("IVA");
        columnBinding.setColumnClass(Float.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${pvp}"));
        columnBinding.setColumnName("PVP");
        columnBinding.setColumnClass(Float.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${materialFamilyId}"));
        columnBinding.setColumnName("Família");
        columnBinding.setColumnClass(org.gesplan.entity.MaterialFamily.class);
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();
        masterTable.addPropertyChangeListener(formListener);
        masterScrollPane.setViewportView(masterTable);
        masterTable.getColumnModel().getColumn(1).setMinWidth(200);
        masterTable.getColumnModel().getColumn(3).setMaxWidth(40);
        masterTable.getColumnModel().getColumn(5).setMinWidth(150);
        this.jTableBinding = jTableBinding;

        idLabel.setText("Id:");

        descriptionLabel.setText("Descripció:");

        pvpLabel.setText("PVP:");

        priceSupplierLabel.setText("Preu proveïdor:");

        ivaLabel.setText("IVA:");

        materialFamilyIdLabel.setText("Família:");

        unitsLabel.setText("Unitats:");

        datePvpLabel.setText("Data PVP:");

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.id}"), idField, org.jdesktop.beansbinding.BeanProperty.create("text"));
        binding.setSourceUnreadableValue(null);
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), idField, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.description}"), descriptionField, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "description");
        binding.setSourceUnreadableValue(null);
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), descriptionField, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.priceSupplier}"), priceSupplierField, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "Preu proveïdor");
        binding.setSourceUnreadableValue(null);
        binding.setConverter(floatToStringConverter1);
        binding.setValidator(floatValidator1);
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), priceSupplierField, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        priceSupplierField.addFocusListener(formListener);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.iva}"), ivaField, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "IVA");
        binding.setSourceUnreadableValue(null);
        binding.setConverter(floatToStringConverter1);
        binding.setValidator(floatValidator1);
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), ivaField, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        ivaField.addFocusListener(formListener);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.units}"), unitsField, org.jdesktop.beansbinding.BeanProperty.create("text"));
        binding.setSourceUnreadableValue(null);
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), unitsField, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        org.jdesktop.swingbinding.JComboBoxBinding jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, materialFamilyList, materialFamilyComboBox, "");
        bindingGroup.addBinding(jComboBoxBinding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.materialFamilyId}"), materialFamilyComboBox, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"), "materialFamilyBindingSelected");
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), materialFamilyComboBox, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        nextButton.setMnemonic('S');
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/gesplan/properties/Bundle"); // NOI18N
        nextButton.setText(bundle.getString("NEXT")); // NOI18N
        nextButton.addActionListener(formListener);

        previousButton.setMnemonic('A');
        previousButton.setText(bundle.getString("PREVIOUS")); // NOI18N
        previousButton.addActionListener(formListener);

        refreshButton.setMnemonic('T');
        refreshButton.setText(bundle.getString("REFRESH")); // NOI18N
        refreshButton.addActionListener(formListener);

        saveButton.setMnemonic('G');
        saveButton.setText(bundle.getString("SAVE")); // NOI18N
        saveButton.addActionListener(formListener);

        deleteButton.setMnemonic('E');
        deleteButton.setText(bundle.getString("DELETE")); // NOI18N
        deleteButton.addActionListener(formListener);

        newButton.setMnemonic('N');
        newButton.setText(bundle.getString("NEW")); // NOI18N
        newButton.addActionListener(formListener);

        javax.swing.GroupLayout buttonsPanelLayout = new javax.swing.GroupLayout(buttonsPanel);
        buttonsPanel.setLayout(buttonsPanelLayout);
        buttonsPanelLayout.setHorizontalGroup(
            buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(buttonsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(newButton, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(previousButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(nextButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(32, Short.MAX_VALUE))
        );
        buttonsPanelLayout.setVerticalGroup(
            buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(buttonsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(saveButton)
                    .addComponent(refreshButton)
                    .addComponent(deleteButton)
                    .addComponent(newButton)
                    .addComponent(previousButton)
                    .addComponent(nextButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.supplierId}"), supplierComboBox, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"), "supplierBindingSelected");
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), supplierComboBox, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        materialFamilyIdLabel1.setText("Proveïdor:");

        jTextArea1.setColumns(20);
        jTextArea1.setRows(3);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.comments}"), jTextArea1, org.jdesktop.beansbinding.BeanProperty.create("text_ON_FOCUS_LOST"), "commentsBinding");
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), jTextArea1, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        jScrollPane1.setViewportView(jTextArea1);

        materialFamilyIdLabel2.setText("Comentaris:");

        pvpDateChooser.setDateFormatString("dd-MM-yyyy");

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.datePvp}"), pvpDateChooser, org.jdesktop.beansbinding.BeanProperty.create("date"));
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement != null}"), pvpDateChooser, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, materialList, filterMaterialComboBox);
        bindingGroup.addBinding(jComboBoxBinding);

        filterMaterialComboBox.addActionListener(formListener);

        jLabel1.setText("Material:");

        jLabel2.setText("Família:");

        jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, materialFamilyList, filterMaterialFamilyComboBox);
        bindingGroup.addBinding(jComboBoxBinding);

        filterMaterialFamilyComboBox.addActionListener(formListener);

        resetButton.setMnemonic('R');
        resetButton.setText(bundle.getString("RESET")); // NOI18N
        resetButton.addActionListener(formListener);

        reportButton.setMnemonic('R');
        reportButton.setText("Informe");
        reportButton.addActionListener(formListener);

        pvpFieldOk.setBackground(new java.awt.Color(212, 208, 200));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("${selectedElement.pvp}"), pvpFieldOk, org.jdesktop.beansbinding.BeanProperty.create("text"), "pvp4");
        bindingGroup.addBinding(binding);
        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, masterTable, org.jdesktop.beansbinding.ELProperty.create("false"), pvpFieldOk, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(materialFamilyIdLabel2)
                            .addComponent(idLabel)
                            .addComponent(priceSupplierLabel)
                            .addComponent(datePvpLabel)
                            .addComponent(materialFamilyIdLabel))
                        .addGap(8, 8, 8)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(materialFamilyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                        .addComponent(priceSupplierField, javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(idField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addComponent(pvpDateChooser, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGap(18, 18, 18)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(ivaLabel)
                                    .addComponent(unitsLabel)
                                    .addComponent(descriptionLabel)
                                    .addComponent(materialFamilyIdLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGap(18, 18, 18)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                    .addComponent(descriptionField, javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(supplierComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 239, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                        .addComponent(ivaField)
                                        .addGap(29, 29, 29)
                                        .addComponent(pvpLabel)
                                        .addGap(10, 10, 10)
                                        .addComponent(pvpFieldOk, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(unitsField, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(161, 161, 161))))
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 564, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(114, 114, 114))
                    .addComponent(masterScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 771, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                .addGap(21, 21, 21)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(filterMaterialFamilyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 323, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(29, 29, 29)
                        .addComponent(reportButton, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(resetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(filterMaterialComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(filterMaterialComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(resetButton)
                    .addComponent(filterMaterialFamilyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(reportButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(masterScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 266, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(idLabel)
                    .addComponent(idField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(descriptionLabel)
                    .addComponent(descriptionField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(priceSupplierField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(ivaLabel)
                    .addComponent(ivaField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(priceSupplierLabel)
                    .addComponent(pvpLabel)
                    .addComponent(pvpFieldOk, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(datePvpLabel)
                        .addComponent(unitsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(unitsLabel))
                    .addComponent(pvpDateChooser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(materialFamilyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(materialFamilyIdLabel)
                    .addComponent(supplierComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(materialFamilyIdLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(materialFamilyIdLabel2))
                .addGap(18, 18, 18)
                .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        bindingGroup.bind();
    }

    // Code for dispatching events from components to event handlers.

    private class FormListener implements java.awt.event.ActionListener, java.awt.event.FocusListener, java.beans.PropertyChangeListener {
        FormListener() {}
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            if (evt.getSource() == nextButton) {
                MaterialPanel.this.nextButtonActionPerformed(evt);
            }
            else if (evt.getSource() == previousButton) {
                MaterialPanel.this.previousButtonActionPerformed(evt);
            }
            else if (evt.getSource() == refreshButton) {
                MaterialPanel.this.refreshButtonActionPerformed(evt);
            }
            else if (evt.getSource() == saveButton) {
                MaterialPanel.this.saveButtonActionPerformed(evt);
            }
            else if (evt.getSource() == deleteButton) {
                MaterialPanel.this.deleteButtonActionPerformed(evt);
            }
            else if (evt.getSource() == newButton) {
                MaterialPanel.this.newButtonActionPerformed(evt);
            }
            else if (evt.getSource() == filterMaterialComboBox) {
                MaterialPanel.this.filterMaterialComboBoxActionPerformed(evt);
            }
            else if (evt.getSource() == filterMaterialFamilyComboBox) {
                MaterialPanel.this.filterMaterialFamilyComboBoxActionPerformed(evt);
            }
            else if (evt.getSource() == resetButton) {
                MaterialPanel.this.resetButtonActionPerformed(evt);
            }
            else if (evt.getSource() == reportButton) {
                MaterialPanel.this.reportButtonActionPerformed(evt);
            }
        }

        public void focusGained(java.awt.event.FocusEvent evt) {
            if (evt.getSource() == priceSupplierField) {
                MaterialPanel.this.priceSupplierFieldFocusGained(evt);
            }
            else if (evt.getSource() == ivaField) {
                MaterialPanel.this.ivaFieldFocusGained(evt);
            }
        }

        public void focusLost(java.awt.event.FocusEvent evt) {
            if (evt.getSource() == priceSupplierField) {
                MaterialPanel.this.priceSupplierFieldFocusLost(evt);
            }
            else if (evt.getSource() == ivaField) {
                MaterialPanel.this.ivaFieldFocusLost(evt);
            }
        }

        public void propertyChange(java.beans.PropertyChangeEvent evt) {
            if (evt.getSource() == masterTable) {
                MaterialPanel.this.masterTablePropertyChange(evt);
            }
        }
    }// </editor-fold>//GEN-END:initComponents


    public static void main(String[] args) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            logger.severe(ex.getMessage());
        }
        //</editor-fold>

        /* Create and display the form */
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setContentPane(new MaterialPanel());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
    // </editor-fold>


    private void masterTablePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_masterTablePropertyChange
        Utils.setRecordInfo(masterTable);
    }//GEN-LAST:event_masterTablePropertyChange

    private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextButtonActionPerformed
        next();
    }//GEN-LAST:event_nextButtonActionPerformed

    private void previousButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_previousButtonActionPerformed
        previous();
    }//GEN-LAST:event_previousButtonActionPerformed

    private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
        refresh(tableQuery);
    }//GEN-LAST:event_refreshButtonActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        save();
    }//GEN-LAST:event_saveButtonActionPerformed

    private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
        delete();
    }//GEN-LAST:event_deleteButtonActionPerformed

    private void newButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newButtonActionPerformed
        newRecord();
    }//GEN-LAST:event_newButtonActionPerformed

    private void filterMaterialComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filterMaterialComboBoxActionPerformed
        changeFilter();
    }//GEN-LAST:event_filterMaterialComboBoxActionPerformed

    private void filterMaterialFamilyComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filterMaterialFamilyComboBoxActionPerformed
        changeFilter();
    }//GEN-LAST:event_filterMaterialFamilyComboBoxActionPerformed

    private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
        resetFilters();
    }//GEN-LAST:event_resetButtonActionPerformed

    private void priceSupplierFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_priceSupplierFieldFocusLost
        changePrice();
    }//GEN-LAST:event_priceSupplierFieldFocusLost

    private void ivaFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_ivaFieldFocusLost
        changePrice();
    }//GEN-LAST:event_ivaFieldFocusLost

    private void reportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reportButtonActionPerformed
        prepareReport();
    }//GEN-LAST:event_reportButtonActionPerformed

    private void priceSupplierFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_priceSupplierFieldFocusGained
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                priceSupplierField.selectAll();
            }
        });
    }//GEN-LAST:event_priceSupplierFieldFocusGained

    private void ivaFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_ivaFieldFocusGained
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ivaField.selectAll();
            }
        });
    }//GEN-LAST:event_ivaFieldFocusGained
    // <editor-fold defaultstate="collapsed" desc="Variables declaration">
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel buttonsPanel;
    private javax.swing.JLabel datePvpLabel;
    private javax.swing.JButton deleteButton;
    private javax.swing.JTextField descriptionField;
    private javax.swing.JLabel descriptionLabel;
    private javax.swing.JComboBox filterMaterialComboBox;
    private javax.swing.JComboBox filterMaterialFamilyComboBox;
    private org.gesplan.util.FloatToStringConverter floatToStringConverter1;
    private org.gesplan.util.FloatValidator floatValidator1;
    private javax.swing.JTextField idField;
    private javax.swing.JLabel idLabel;
    private javax.swing.JTextField ivaField;
    private javax.swing.JLabel ivaLabel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JScrollPane masterScrollPane;
    private javax.swing.JTable masterTable;
    private javax.swing.JComboBox materialFamilyComboBox;
    private javax.swing.JLabel materialFamilyIdLabel;
    private javax.swing.JLabel materialFamilyIdLabel1;
    private javax.swing.JLabel materialFamilyIdLabel2;
    private java.util.List<org.gesplan.entity.MaterialFamily> materialFamilyList;
    private javax.persistence.Query materialFamilyQuery;
    private java.util.List<org.gesplan.entity.Material> materialList;
    private javax.persistence.Query materialQuery;
    private javax.swing.JButton newButton;
    private javax.swing.JButton nextButton;
    private javax.swing.JButton previousButton;
    private javax.swing.JTextField priceSupplierField;
    private javax.swing.JLabel priceSupplierLabel;
    private com.toedter.calendar.JDateChooser pvpDateChooser;
    private javax.swing.JTextField pvpFieldOk;
    private javax.swing.JLabel pvpLabel;
    private javax.swing.JButton refreshButton;
    private javax.swing.JButton reportButton;
    private javax.swing.JButton resetButton;
    private javax.swing.JButton saveButton;
    private javax.swing.JComboBox supplierComboBox;
    private java.util.List<org.gesplan.entity.Material> tableList;
    private javax.persistence.Query tableQuery;
    private javax.swing.JTextField unitsField;
    private javax.swing.JLabel unitsLabel;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
    // </editor-fold>
}